using System;
using System.Collections.Generic;
using System.Text;
using Common.Shared.Design;
using System.Reflection;

namespace Common.Shared.Reflection {
	internal static class AttributeUtils {

		public static WddxRootAttribute GetWddxRoot ( Type type ) {
			return GetAttribute<WddxRootAttribute> ( type );
		}

		public static WddxAttributeAttribute GetWddxAttribute ( MemberInfo mi ) {
			return GetAttribute<WddxAttributeAttribute> ( mi );
		}

		public static WddxElementAttribute GetWddxElement ( MemberInfo mi ) {
			return GetAttribute<WddxElementAttribute> ( mi );
		}

		public static bool IsWddxElement ( MemberInfo mi ) {
			return ( GetAttribute<WddxElementAttribute> ( mi ) != null || GetAttribute<WddxRootAttribute> ( mi ) != null ) && !IsWddxText(mi);
		}

		public static bool IsWddxAttribute ( MemberInfo mi ) {
			return GetAttribute<WddxAttributeAttribute> ( mi ) != null && !IsWddxText(mi);
		}

		public static bool IsWddxText ( MemberInfo mi ) {
			return GetAttribute<WddxTextAttribute> ( mi ) != null;
		}

		public static bool IsWddxIgnore ( MemberInfo mi ) {
			return GetAttribute<WddxIgnoreAttribute> ( mi ) != null;
		}

		public static Type GetTypeFromRootName ( string name ) {
			Type[] types = typeof(AttributeUtils).Assembly.GetTypes();
			foreach ( Type t in types ) {
				WddxRootAttribute root = GetAttribute<WddxRootAttribute> ( t );
				if ( root != null && string.Compare ( root.ElementName, name, false ) == 0 ) {
					return t;
				}
			}
			return null;
		}

		public static int GetWddxOrder ( MemberInfo mi ) {
			WddxOrderAttribute woa = GetAttribute<WddxOrderAttribute> ( mi );
			if ( woa == null ) {
				return 0;
			} else {
				return woa.Order;
			}
		}

		public static T GetAttribute<T> ( Type t ) where T : Attribute {
			foreach ( Attribute attr in t.GetCustomAttributes ( true ) ) {
				if ( attr is T ) {
					return (T)attr;
				}
			}
			return default ( T );
		}

		public static T GetAttribute<T> ( MemberInfo mi ) where T : Attribute {
			foreach ( Attribute attr in mi.GetCustomAttributes ( true ) ) {
				if ( attr is T ) {
					return (T)attr;
				}
			}
			return default ( T );
		}
	}
}
